<script setup lang="ts">
import { computed, onMounted } from 'vue'
import { ElButton, ElInput } from 'element-plus'
import type { Node } from '@/types/schema'
import Container from './Container.vue'
import Grid from './Grid.vue'
import Tabs from './Tabs.vue'
import { componentRegistry } from '@/core/ComponentRegistry'
import { useRenderer } from '@/composables/useRenderer'
import { useEditorStore } from '@/stores/editor'


const props = defineProps<{ node: Node }>()
const emit = defineEmits<{
  (e: 'select', id: string): void,
  (e: 'update:node', node: Node): void
}>()

const store = useEditorStore()
const { registerNode, executeEventActions } = useRenderer()

onMounted(() => {
  registerNode(props.node)
})
const handleDragOver = (event: DragEvent) => {
  event.preventDefault()
  if (event.dataTransfer) {
    event.dataTransfer.dropEffect = 'copy'
  }
}
const handleDrop = (event: DragEvent) => {
  event.preventDefault()
  if (!event.dataTransfer) return

  try {
    const data = event.dataTransfer.getData('text/plain')
    const componentData = JSON.parse(data)

    // 添加组件到页面
    store.addNode(componentData.type, componentData.component)
  } catch (e) {
    console.error('Failed to parse dropped component data:', e)
  }
}
const dynamicComponent = computed(() => {
  if (props.node.type !== 'custom') return null
  const reg = componentRegistry.get(props.node.component!)
  return reg?.component || null
})

const eventListeners = computed(() => {
  const listeners: Record<string, (...args: unknown[]) => void> = {};
  if (props.node.events) {
    for (const eventName in props.node.events) {
      listeners[eventName] = (...args: unknown[]) => {
        const actions = props.node.events?.[eventName];
        if (actions) {
          executeEventActions(actions, props.node.id);
        }
      };
    }
  }
  return listeners;
});



const handleClick = () => {
  if (props.node.events?.click) {
    executeEventActions(props.node.events.click, props.node.id)
  }
}
</script>

<template>
  <div
    v-if="node.type === 'page'"
    class="page-renderer"
    @dragover="handleDragOver"
    @drop="handleDrop"
  >
    <Renderer
      v-for="child in node.children"
      :key="child.id"
      :node="child"
      @select="$emit('select', child.id)"
    />
  </div>

  <ElButton
    v-else-if="node.type === 'button'"
    :style="{ margin: '8px' }"
    @click="handleClick"
    @click.stop="$emit('select', node.id)"
  >
    {{ node.props.text }}
  </ElButton>

  <ElInput
    v-else-if="node.type === 'input'"
    :model-value="node.props.value"
    :placeholder="node.props.placeholder"
    :style="{ margin: '8px' }"
    @input="(val) => emit('update:node', { ...node, props: { ...node.props, value: val } })"
    @click.stop="$emit('select', node.id)"
  />

  <Container
    v-else-if="node.type === 'container'"
    :node="node"
    @select="$emit('select', $event)"
  />

  <Grid
    v-else-if="node.type === 'grid'"
    :node="node"
    @select="$emit('select', $event)"
  />

  <Tabs
    v-else-if="node.type === 'tabs'"
    :node="node"
    @select="$emit('select', $event)"
  />

  <component
    v-else-if="node.type === 'custom'"
    :is="dynamicComponent"
    v-bind="node.props"
    v-on="eventListeners"
    @click.stop="$emit('select', node.id)"
  />

  <div
    v-else
    @click.stop="$emit('select', node.id)"
    @dragover="handleDragOver"
    @drop="handleDrop"
  >
    <Renderer
      v-for="child in node.children"
      :key="child.id"
      :node="child"
      @select="$emit('select', child.id)"
    />
  </div>
</template>

<style scoped>
.page-renderer {
  min-height: 400px;
  background-color: #f5f5f5;
  padding: 16px;
  border: 1px dashed #ccc;
}
</style>
